package com.ke.jun.bg.petpackmvvm.base.fragmnet

import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import com.ke.jun.bg.petpackmvvm.base.viewmodel.BaseViewModel
import com.ke.jun.bg.petpackmvvm.ext.getVmClazz
import com.ke.jun.bg.petpackmvvm.network.manager.NetState
import com.ke.jun.bg.petpackmvvm.network.manager.NetworkStateManager

/**
 * 描述　: ViewModelFragment基类，自动把ViewModel注入Fragment
 */
abstract  class BaseVmFragment<VM:BaseViewModel>:Fragment() {
    protected val handler=Handler(Looper.getMainLooper())
    //是否第一次加载
    protected var isFirst:Boolean=true

    lateinit var mViewModel: VM

    lateinit var mActivity: AppCompatActivity

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(layoutId(),container,false)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        mActivity=context as AppCompatActivity
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        isFirst=true
        mViewModel=createViewModel()
        initView(savedInstanceState)
        createObserver()
        registorDefUIChange()
        initData()
    }

    private fun registorDefUIChange() {
         mViewModel.loadingChange.showDialog.observeInFragment(this){
             showLoading(it)
         }

        mViewModel.loadingChange.dismissDialog.observeInFragment(this){
            dismissLoading()
        }
    }
    /**
     * Fragment执行onCreate后触发的方法
     */
    open fun initData() {}

    abstract fun showLoading(message: String = "请求网络中...")

    abstract fun dismissLoading()

    /**
     * 创建观察者
     */
    abstract fun createObserver()

    /**
     * 初始化view
     */
    abstract fun initView(savedInstanceState: Bundle?)
    /**
     * 创建viewModel
     */
    private fun createViewModel(): VM {
        return ViewModelProvider(this).get(getVmClazz(this))
    }

    /**
     * 加载布局ID
     */
    abstract fun layoutId(): Int
    /**
     * 将非该Fragment绑定的ViewModel添加 loading回调 防止出现请求时不显示 loading 弹窗bug
     * @param viewModels Array<out BaseViewModel>
     */
    protected fun addLoadingObserve(vararg viewModels: BaseViewModel) {
        viewModels.forEach { viewModel ->
            //显示弹窗
            viewModel.loadingChange.showDialog.observeInFragment(this) {
                showLoading(it)
            }
            //关闭弹窗
            viewModel.loadingChange.dismissDialog.observeInFragment(this) {
                dismissLoading()
            }
        }
    }

    override fun onResume() {
        super.onResume()
        onVisible()
    }
    /**
     * 是否需要懒加载
     */
    private fun onVisible() {
     if (lifecycle.currentState==Lifecycle.State.STARTED&&isFirst){
         //延迟加载 防止 切换动画还没执行完毕时数据就已经加载好了，这时页面会有渲染卡顿
         handler.postDelayed({
           lazyLoadData()
             //在Fragment中，只有懒加载过了才能开启网络变化监听
             NetworkStateManager.instance.mNetworkStateCallback.observeInFragment(this){
                 if (!isFirst){
                     onNetWorkStateChanged(it)
                 }
             }

             isFirst=false
         },lazyLoadTime())
     }
    }

    /**
     * 网络变化监听 子类重写
     */
    private fun onNetWorkStateChanged(it: NetState?) {

    }

    /**
     * 懒加载
     */
    abstract fun lazyLoadData()

    /**
     * 延迟加载 防止 切换动画还没执行完毕时数据就已经加载好了，这时页面会有渲染卡顿  bug
     * 这里传入你想要延迟的时间，延迟时间可以设置比转场动画时间长一点 单位： 毫秒
     * 不传默认 300毫秒
     * @return Long
     */
    open fun lazyLoadTime(): Long {
        return 300
    }

    override fun onDestroy() {
        super.onDestroy()
        handler.removeCallbacksAndMessages(null)
    }
}